﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Caliburn.PresentationFramework.ApplicationModel;
using Caliburn.PresentationFramework;
using IronCommander.Domain;
using System.Windows.Data;
using IronCommander.Utils;
using System.IO;

namespace IronCommander.ViewModels
{
    public class FileTabViewModel : Navigator
    {
        readonly FileLoader fileLoader;
        readonly CurrentPaths currentPaths;


        string informationMessage;
        public string InformationMessage { get { return informationMessage; } set { this.SetValue(ref informationMessage, value, () => InformationMessage); } }

        string errorMessage;
        public string ErrorMessage { get { return errorMessage; } set { this.SetValue(ref errorMessage, value, () => ErrorMessage); } }


        BindableCollection<FileViewModel> files;
        public BindableCollection<FileViewModel> Files { get { return files; } set { this.SetValue(ref files, value, () => Files, OnFilesChanged); } }

        FileViewModel currentFile;
        public FileViewModel CurrentFile { get { return currentFile; } set { this.SetValue(ref currentFile, value, () => CurrentFile); } }


        public BindableCollection<DriveViewModel> Drives { get; private set; }

        DriveViewModel currentDrive;
        public DriveViewModel CurrentDrive { get { return currentDrive; } set { this.SetValue(ref currentDrive, value, () => CurrentDrive, OnCurrentDriveChanged); } }

        void OnCurrentDriveChanged()
        {
            Navigate(currentPaths[CurrentDrive]);
        }


        string previousPath;
        public string PreviousPath { get { return previousPath; } set { this.SetValue(ref previousPath, value, () => PreviousPath); } }

        string currentPath;
        public string CurrentPath 
        {
            get { return currentPath; }
            private set { this.SetValue(ref currentPath, value, () => CurrentPath, OnCurrentPathChanged); }
        }

        void OnCurrentPathChanged()
        {
            UpdateDisplayName();
            Refresh(); 
        }

        public void Navigate(string path)
        {
            if (path.IsBlank())
                return;

            PreviousPath = CurrentPath;
            Navigate(completed => { CurrentPath = path; completed(true); }, _ => { });
        }

        public void GoUp()
        {
            Navigate(Path.GetDirectoryName(CurrentPath));
        }


        void OnFilesChanged()
        {
            var filesView = (ListCollectionView)CollectionViewSource.GetDefaultView(files);
            filesView.CustomSort = new FileSortingComparer();
        }


        public void Refresh()
        {
            Files = fileLoader.Load(CurrentPath);
            // TODO: This works for synchronous scenarios only
            CurrentFile = Files.FirstOrDefault(f => f.FullName == PreviousPath) ?? Files.FirstOrDefault();
        }

        public void Open(FileViewModel file)
        {
            if (file == null)
                return;

            if (file.IsFolder)
                Navigate(file.FullName);
            else
                ErrorMessage = "Can't open file yet";
        }

        public void OpenCurrentFile()
        {
            Open(CurrentFile);
        }


        public FileTabViewModel(IFileSystemInfoProvider fileSystemInfoProvider, CurrentPaths currentPaths)
        {
            this.currentPaths = currentPaths;
            this.fileLoader = new FileLoader(fileSystemInfoProvider);

            Drives = fileSystemInfoProvider.GetDrives().ToBindable();

            CurrentDrive = Drives.First();
        }

        void UpdateDisplayName()
        {
            DisplayName = CurrentPath;
        }
    }
}
